package main

import (
    "fmt"
    "reflect"
)

// reflect包中有两个重要的方法 typeOf() 和 valueOf():
// typeOf: 传入任意类型，获得具体的类型
// valueOf: 传入任意类型，获得具体的值

func reflectObject(arg interface{})  {
    fmt.Println("type=", reflect.TypeOf(arg))
    fmt.Println("value=", reflect.ValueOf(arg))
}

func reflectFielfAndMethod(arg interface{})  {
    fmt.Println("reflectFielfAndMethod 被调用...")
    argType:= reflect.TypeOf(arg)
    argValue := reflect.ValueOf(arg)
    //1.获取interface的reflect.Type，通过Type获得Fields，进行遍历
    fieldNum := argType.Elem().NumField()
    for i := 0; i < fieldNum; i++ {
       field := argType.Elem().Field(i)
       value := argValue.Elem().Field(i).Interface()
       fmt.Printf("属性：%s: %v = %v\n", field.Name, field.Type, value)
    }

    // 2.通过type获得累不分方法，并进行调用(类似于Field)
    methodNum := argType.NumMethod()
    fmt.Println("methodNum:", methodNum)
    for i := 0; i < methodNum; i++ {
        method := argType.Method(i)
        fmt.Printf("方法：%s:%s\n", method.Name, method.Type)
    }

}

type User struct {
    Id int
    Name string
}

func (this User) CallValue()  {
    fmt.Println("CallValue() is called...")
}

func (this *User) CallPoint()  {
    fmt.Println("CallPoint() is called...")
}

func main() {
    var num float64 = 1.2345
    reflectObject(num)  // type= float64    value= 1.2345

    user := User{1, "jiguiquan"}
    reflectObject(user)  // type= main.User   value= {1 jiguiquan}
    reflectFielfAndMethod(&user)  //Id: int = 1     Name: string = jiguiquan
}
